home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_184
/
world
/
parser.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
18KB
|
871 lines
#include "parame.inc"
#include "variab.h"
#include "arrays.h"
#include "vocab.inc"
#include "verbtb.inc"
#define abs(A) ((A < 0) ? -A : A)
/* World C Version 1.00 copyright 1987 J.D.McDonald
Use as you like for non-commercial purposes, but please
leave this note, and document any changes you make as yours */
/* No apologies for all the goto's. If you can get rid of them, well,
I guess some persons are just naturally masochists */
static int typlst[4] = {VRBMIN, ADJMIN, NUNMIN, PRPMIN};
static int index[5], indx;
scan()
/*
* this function scans the input line for gross syntax errors it also expands
* special direction commands such as "ne" into their full form. it also
* works on adverbs, removes such expressions as "ask frog," etc. finally it
* puts the word numbers and types in the wrdnum and wrdtyp arrays the input
* is inbuf ,the output is wrdnum,wrdtyp,actor,adverb
*
*/
{
int result, offlg, askx, lptr0, wptr, i, lxx, errno;
result = 0;
offlg = 0;
chgact = 0;
askx = 0;
lab5:
adverb = 0;
for (i = 0; i < 30; i++) {
wrdnum[i] = 0;
wrdtyp[i] = 0;
}
/*
* wordtyp is -1 for a period,-2 comma 1 for adverb,2 verb,3 adjective,4
* noun,5 preposition numbers are type 4,and wrdnum=number+10000
*/
wptr = 0;
lab10:
lptr0 = lptr;
wscan();
/*
* on return from wscan punct contains: 0 for a word 1 for a period 2 for
* a comma 3 for a number 4 if an illegal character 5 if a number follows
* a letter directly 6 if a letter follows a number directly
*/
if (punct == 1)
return (result);
else if (punct == 4)
goto lab9000;
else if (punct == 2)
goto lab9010;
else if (punct == 3)
goto lab9019;
else if (punct == 5)
goto lab9020;
else if (punct == 6)
goto lab9140;
else;
/* it's a real word, so find out what it is */
find(VOCMAX);
/* discard buzzword */
if (indx > 0 && indx <= BUZMAX)
goto lab10;
if (indx == 0)
goto lab9040;
if ((indx >= NORTH && indx <= NORTHW) || indx == UP
|| indx == DOWN) {
/* yes,it's a special word */
lptr0 = lptr;
wscan();
/* check if it's all that's on the line */
if (punct != 1)
goto lab9030;
/* expand a direction word into full form */
wrdtyp[1] = 4;
wrdnum[1] = indx;
wrdnum[0] = GO;
wrdtyp[0] = 2;
wrdtyp[2] = -1;
goto lab9999;
}
if (index[0] != 0) {
if (adverb != 0)
goto lab9070;
/* adverbs are removed from the wrdtyp list and handled separately */
adverb = index[0];
if (adverb != WHERE && adverb != WHAT)
goto lab10;
if (actor == 1 || askx != ASK)
goto lab9130;
goto lab10;
}
if (index[1] == 0)
goto lab9050;
wrdtyp[wptr] = 2;
wrdnum[wptr] = index[1];
/*
* we've found the verb check for legal question
*/
if ((adverb == WHAT || adverb == WHERE) - (wrdnum[0] == IS))
goto lab9130;
if (wrdnum[0] == YELL) {
/* the player is told to use "ask" or "tell" */
lab131:
wscan();
if (punct != 1)
goto lab131;
wrdtyp[0] = 2;
wrdnum[0] = YELL;
result = 1;
return (result);
}
if (wrdnum[0] < SHIT)
goto lab200;
/*
* special handling for words which take no objects or modifiers they
* should be alone on a line. they are verbs >= shit
*/
lptr0 = lptr;
wscan();
{
if (punct == 1)
goto lab9998;
else if (punct == 5)
goto lab9120;
else
goto lab9150;
}
/* inner loop for all words after verb */
lab200:
wptr += 1;
if (wptr > 27)
goto lab9180;
lab201:
lptr0 = lptr;
wscan();
if (punct != 0)
goto lab210;
find(BUZMAX);
/* special code for "noun1 of noun2" construct */
if (indx == 4 && wrdtyp[wptr - 1] == 4)
offlg = 1;
if (indx != 0)
goto lab201;
goto lab215;
lab210:
if (punct == 4)
goto lab9000;
if (punct == 5)
goto lab9020;
if (punct == 6)
goto lab9140;
if (punct != 2)
goto lab215;
if (wrdtyp[wptr - 1] != 4)
goto lab9010;
wrdtyp[wptr] = -2;
goto lab200;
lab215:
if (wrdtyp[wptr - 1] != 2 || (wrdnum[wptr - 1] != ASK
&& wrdnum[wptr - 1] != TELL))
goto lab220;
if (punct == 3)
goto lab9019;
if (punct != 0)
goto lab9010;
if (actor != 1)
goto lab9100;
/*
* this code is to set up addressing a second "person" the phrases "ask
* frog" or "tell frog" etc are discarded and the variable "actor" tells
* us who is addressed
*/
askx = wrdnum[wptr - 1];
find(VOCMAX);
if ((index[3] != 0) &&
(index[3] < ROBOT || index[3] > FERRET))
goto lab9090;
if (index[3] == 0)
goto lab9160;
actor = index[3];
lptr0 = lptr;
chgact = 1;
wscan();
if (punct != 2)
goto lab9110;
goto lab5;
/* code for numbers inputted in a statement */
lab220:
if (punct != 3)
goto lab240;
wrdtyp[wptr] = 4;
wrdnum[wptr] = three[0] + 10000;
goto lab200;
/* all regular words go here */
lab240:
if (punct != 1)
goto lab250;
wrdtyp[wptr] = -1;
goto lab9999;
lab250:
find(VOCMAX);
if (indx == 0)
goto lab9040;
/* special code for "of" handler */
if (offlg) {
offlg = 0;
if (index[3] != 0 && wrdtyp[wptr - 2] != 3) {
/* exchange two nouns and tell parser the first is an adjective */
wrdtyp[wptr] = wrdtyp[wptr - 1];
wrdnum[wptr] = wrdnum[wptr - 1];
wrdtyp[wptr - 1] = 3;
wrdnum[wptr - 1] = index[3];
if (wrdnum[wptr] == PHOTOG && wrdnum[wptr - 1] == FERRET) {
wrdnum[wptr - 1] = FAMILY;
}
goto lab200;
}
else
goto lab9200;
}
if (indx != AND)
goto lab270;
if (wrdtyp[wptr - 1] == -2)
goto lab201;
if (wrdtyp[wptr - 1] != 4)
goto lab9120;
wrdtyp[wptr] = -2;
goto lab200;
lab270:
if (index[1] != 0 && index[0] == 0 && index[2] == 0
&& index[3] == 0 && index[4] == 0)
goto lab9080;
if (index[0] == 0)
goto lab280;
if (adverb != 0)
goto lab9070;
adverb = indx;
if (adverb == WHERE || adverb == WHAT)
goto lab9130;
goto lab201;
/* at this point the word must be an adjectine, noun or preposition */
lab280:
if (wrdtyp[wptr - 1] == 3 && index[2] != 0)
goto lab9170;
if (index[2] != 0) {
wrdtyp[wptr] = 3;
wrdnum[wptr] = index[2];
} else if (index[3] != 0) {
wrdtyp[wptr] = 4;
wrdnum[wptr] = index[3];
} else {
wrdtyp[wptr] = 5;
wrdnum[wptr] = index[4];
}
if ((wrdtyp[wptr] == 4 && wrdtyp[wptr - 1] == 3) &&
wrdnum[wptr] < SAPPHI)
goto lab9190;
goto lab200;
/*********** error processing */
lab9000:
lxx = lptr;
errno = 1;
goto lab9900;
lab9010:
lxx = lptr;
errno = 2;
goto lab9900;
lab9019:
lptr -= 1;
lab9020:
lptr += 1;
lxx = lptr;
errno = 3;
goto lab9900;
lab9030:
lxx = lptr;
errno = 4;
goto lab9900;
lab9040:
lxx = lptr;
errno = 5;
goto lab9900;
lab9050:
lxx = lptr;
errno = 6;
goto lab9900;
lab9070:
lxx = lptr;
errno = 8;
goto lab9900;
lab9080:
lxx = lptr;
errno = 9;
goto lab9900;
lab9090:
lxx = 0;
errno = 10;
goto lab9900;
lab9100:
lxx = 0;
errno = 11;
goto lab9900;
lab9110:
lxx = lptr0 + 1;
errno = 12;
goto lab9900;
lab9120:
lxx = lptr;
errno = 13;
goto lab9900;
lab9130:
lxx = 0;
errno = 14;
goto lab9900;
lab9140:
lxx = lptr;
errno = 15;
goto lab9900;
lab9150:
lxx = lptr0;
errno = 16;
goto lab9900;
lab9160:
lxx = 0;
errno = 17;
goto lab9900;
lab9170:
lxx = lptr;
errno = 18;
goto lab9900;
lab9180:
lxx = 0;
errno = 25;
goto lab9900;
lab9190:
lxx = lptr;
errno = 107;
goto lab9900;
lab9200:
lxx = lptr;
errno = 112;
lab9900:
carerr(lxx, errno);
return (result);
lab9998:
wrdtyp[1] = -1;
lab9999:
if ((askx == TELL && (adverb == WHERE || adverb == WHAT))
|| (askx == ASK && (adverb != WHERE && adverb != WHAT)))
goto lab9130;
if (adverb == WHERE || adverb == WHAT)
dotflg = 1;
result = 1;
return (result);
}
wscan()
/*
* this routine reads the input ascii code and scans for punctuation or
* numbers and then converts the first 9 letters of a word to three integer*2
* words of radix 32 form
*/
{
char m;
static int pow32[] = {1, 32, 1024, 32768};
int plcpnt, wpnt, kchar;
if (dotflg) {
actor = 1;
dotflg = 0;
}
plcpnt = 1;
punct = 0;
wpnt = 1;
three[0] = 0;
three[1] = 0;
three[2] = 0;
while (inbuf[lptr] == ' ')
lptr++;
/*
* punct =1 is period, 2 is comma, 3 is number,4 is illegal character and
* 5 means a number directly follows a word 6 means letter follows a
* number
*/
if (inbuf[lptr] == '.' || inbuf[lptr] == '?') {
dotflg = 1;
punct = 1;
lptr += 1;
return (0);
}
if (inbuf[lptr] == ',') {
punct = 2;
lptr += 1;
return (0);
}
while (inbuf[lptr] >= '0' && inbuf[lptr] <= '9') {
/* number handling */
punct = 3;
if (three[0] < 3200)
three[0] = three[0] * 10 + inbuf[lptr] - '0';
lptr += 1;
}
if (punct == 3 && (inbuf[lptr] != '.' &&
inbuf[lptr] != ',' && inbuf[lptr] != '?' &&
inbuf[lptr] != ' '))
punct = 6;
if (punct == 3 || punct == 6)
return (0);
do {
if (!((inbuf[lptr] >= 'a' && inbuf[lptr] <= 'z') ||
(inbuf[lptr] >= 'A' && inbuf[lptr] <= 'Z'))) {
lptr += 1;
punct = 4;
return (0);
/* the actual letter packing is done here */
}
kchar = inbuf[lptr];
if (kchar >= 'a' && kchar <= 'z')
kchar -= ' ';
if (wpnt < 4)
three[wpnt - 1] = three[wpnt - 1] +
(kchar - '@') * pow32[3 - plcpnt];
plcpnt += 1;
if (plcpnt >= 4) {
wpnt += 1;
plcpnt = 1;
}
lptr += 1;
m = inbuf[lptr];
if (m == ' ' || m == ',' || m == '.' || m == '?') {
if (three[0] != 20741 || three[1] != 14336 ||
three[2] != 0)
return (0);
punct = 1;
return (0);
}
}
while (m < '0' || m > '9');
punct = 5;
return (0);
}
find(m)
int m;
{
/*
* this routine searches a vocabulary to find a word. index, on output,
* gives the position of the word in the list. synonyms do not increment
* the counter, so index*3-2 is **not** the actual pointer to the word in
* the list
*/
int i, t, k, type;
for (i = 0; i < 5; i++)
index[i] = 0;
t = 0;
indx = 0;
for (i = 1; i <= m * 3 - 2; i += 3) {
if (vocab[i] > 0)
indx += 1;
if (abs(vocab[i]) != three[0])
continue;
if (vocab[i + 1] != three[1])
continue;
if (vocab[i + 2] == three[2]) {
t = indx;
type = 1;
for (k = 1; k <= 4; k++)
if (indx >= typlst[k - 1])
type = type + 1;
index[type - 1] = indx;
}
}
indx = t;
}
lbit(arg, pow)
int arg, pow;
{
return ((arg & (1 << pow)) != 0);
}
parse()
{
/*
* subroutine parse this mess deciphers the various direct and indirect
* (i.e. second, usually, but in 'give frog cup' the frog is the i.o.)
* objects. it associates them with their respective adjectives (dobjs(i)
* and doadjs(i) correspond) butflg is set if the "all but" construct is
* encountered allflg is set if the "all" construct is enconntered the
* d.o. and i.o prepositions are put in prepdo and prepio
*/
int result, wptr, thevrb, vrbind, vdo, vio, vobj, i;
int frstaj, frstnn, errno, tprp;
result = 0;
thevrb = wrdnum[0];
vrbind = thevrb - VRBMIN + 1;
vdo = 0;
vio = 0;
vobj = 0;
if (thevrb < SHIT) {
vdo = vrbpdo[vrbind];
vio = vrbpio[vrbind];
vobj = vrbobj[vrbind];
}
butflg = 0;
allflg = 0;
numdo = 0;
prepdo = 0;
prepio = 0;
iobj = 0;
ioadj = 0;
for (i = 0; i < 12; i++) {
dobjs[i] = 0;
doadjs[i] = 0;
}
/* this block is a test for "sit down" or "get up" or "look up" etc */
if (((lbit(vobj, 1) && wrdnum[1] == DOWN) ||
(lbit(vobj, 2) && wrdnum[1] == UP)) && wrdtyp[2] == -1) {
prepdo = wrdnum[1];
result = 1;
goto finalout;
}
/* yell allows anything after it */
if (thevrb == YELL)
goto testout;
wptr = 1;
frstaj = 0;
frstnn = 0;
/* a preposition immediately follows verb */
if (wrdtyp[wptr] == 5) {
prepdo = wrdnum[wptr];
if (prepdo == BUT) {
errno = 21;
goto errorout;
}
if (!lbit(vdo, (prepdo - PRPMIN))) {
errno = 21;
goto errorout;
}
wptr += 1;
}
/*
* adjective follows verb *** special case of "terran" and "cygnan" as
* nouns
*/
if (wrdtyp[wptr] == 3) {
if ((wrdnum[wptr] == TERRAN || wrdnum[wptr] == CYGNAN)
&& wrdnum[0] == TRANSL)
wrdtyp[wptr] = 4;
else {
frstaj = wrdnum[wptr];
doadjs[0] = frstaj;
wptr += 1;
}
}
/* this takes care of the case of a verb alone on a line */
if (wrdtyp[wptr] != 4) {
if (wrdtyp[wptr] != -1) {
errno = 28;
goto errorout;
} else {
{
if (thevrb >= SHIT) {
result = 1;
goto finalout;
}
if (!lbit(vobj, 7)) {
result = 1;
goto finalout;
}
}
errno = 27;
goto errorout;
}
}
frstnn = wrdnum[wptr];
/* look at first set of objects (not always d.o.) */
dobjs[0] = frstnn;
numdo += 1;
if (numdo == 9) {
errno = 25;
goto errorout;
}
wptr += 1;
/* the following takes care of multiple objects */
if (frstnn == ALL) {
if (!lbit(vobj, 5)) {
errno = 22;
goto errorout;
}
if (frstaj != 0) {
errno = 26;
goto errorout;
}
allflg = 1;
if (wrdnum[wptr] == BUT) {
butflg = 1;
/* check for adjective before noun */
if (!(wrdtyp[wptr + 1] == 4 || (wrdtyp[wptr + 1] == 3
&& wrdtyp[wptr + 2] == 4))) {
errno = 23;
goto errorout;
}
wptr += 1;
}
}
if (butflg || (wrdtyp[wptr] == -2)) {
if (!lbit(vobj, 5)) {
errno = 22;
goto errorout;
}
mulobj(&wptr);
if (numdo > 9) {
errno = 25;
goto errorout;
}
}
/********** end multiple obj processor */
if (wrdtyp[wptr] == -1)
goto testout;
/* if the verb is "is" we may have a final adjective */
if (thevrb == IS && wrdtyp[wptr] == 3) {
doadjs[1] = wrdnum[wptr];
if (wrdtyp[wptr + 1] == -1)
goto testout;
errno = 20;
goto errorout;
}
/*
* if the next word is a noun or adjective, and verb is not "is" we have
* a non-prep indirect object such as the frog in "give frog water"
*/
if (wrdtyp[wptr] == 4 || (wrdtyp[wptr] == 3 && wrdtyp[wptr + 1]
== 4)) {
if (numdo > 1 || prepdo != 0) {
errno = 22;
goto errorout;
}
if (!lbit(vobj, 3)) {
errno = 24;
goto errorout;
}
prepio = TO;
ioadj = frstaj;
iobj = frstnn;
doadjs[0] = 0;
if (wrdtyp[wptr] == 3) {
doadjs[0] = wrdnum[wptr];
wptr += 1;
}
dobjs[0] = wrdnum[wptr];
numdo = 1;
wptr += 1;
/****** repeat the multiple obj processor */
if (dobjs[0] == ALL) {
if (!lbit(vobj, 5)) {
errno = 22;
goto errorout;
}
if (doadjs[0] != 0) {
errno = 26;
goto errorout;
}
allflg = 1;
if (wrdtyp[wptr] == 5 && wrdnum[wptr] == BUT) {
butflg = 1;
if (!(wrdtyp[wptr + 1] == 4 || (wrdtyp[wptr + 1] == 3
&& wrdtyp[wptr + 2] == 4))) {
errno = 23;
goto errorout;
}
}
}
if (butflg || wrdtyp[wptr] == -2) {
if (!lbit(vobj, 5)) {
errno = 22;
goto errorout;
}
mulobj(&wptr);
if (numdo > 9) {
errno = 25;
goto errorout;
}
}
/***** end multiple object processor */
if (wrdtyp[wptr] != -1) {
errno = 20;
goto errorout;
}
goto testout;
}
/* the only thing left that is legal is a perpositional construct */
if (wrdtyp[wptr] != 5 || wrdnum[wptr] == BUT || (
wrdtyp[wptr + 1] == 5 && wrdnum[wptr + 1] == BUT)) {
errno = 20;
goto errorout;
}
tprp = wrdnum[wptr];
wptr += 1;
/*
* check for end of line or two preps in a row (e.g. fill the bottle up
* with water)
*/
if (wrdtyp[wptr] == -1 || wrdtyp[wptr] == 5) {
if (prepdo != 0 || (!lbit(vdo, (tprp - PRPMIN)))
|| (!lbit(vobj, 0))) {
errno = 20;
goto errorout;
}
prepdo = tprp;
if (wrdtyp[wptr] == -1)
goto testout;
wptr += 1;
}
if (!lbit(vio, (wrdnum[wptr - 1] - PRPMIN))) {
errno = 20;
goto errorout;
}
prepio = wrdnum[wptr - 1];
if (wrdtyp[wptr] == 3) {
ioadj = wrdnum[wptr];
wptr += 1;
}
if (wrdtyp[wptr] != 4) {
errno = 20;
goto errorout;
}
iobj = wrdnum[wptr];
wptr += 1;
if (wrdtyp[wptr] != -1) {
errno = 20;
goto errorout;
}
testout:
if ((dobjs[0] == 0 && lbit(vobj, 7)) || (iobj == 0 &&
lbit(vobj, 6))) {
errno = 20;
goto errorout;
}
if (!lbit(vobj, 4) && dobjs[0] != 0 && prepdo == 0) {
errno = 19;
goto errorout;
}
result = 1;
finalout:
if (wrdnum[0] == AGAIN) {
for (i = 0; i < 12; i++) {
doadjs[i] = zadjs[i];
dobjs[i] = zobjs[i];
}
ioadj = ziadj;
iobj = ziobj;
prepdo = zpdo;
prepio = zpio;
actor = zactor;
adverb = zadvrb;
wrdnum[0] = zverb;
numdo = znumb;
allflg = zall;
butflg = zbut;
} else {
for (i = 0; i < 12; i++) {
zadjs[i] = doadjs[i];
zobjs[i] = dobjs[i];
}
ziadj = ioadj;
ziobj = iobj;
zpdo = prepdo;
zpio = prepio;
zactor = actor;
zadvrb = adverb;
zverb = wrdnum[0];
zall = allflg;
zbut = butflg;
}
return (result);
errorout:
carerr(0, errno);
return (result);
}
mulobj(wptr)
int *wptr;
{
/**** multiple opject subroutine from "parse" */
while (1) {
if (wrdtyp[*wptr] == 3) {
doadjs[numdo] = wrdnum[*wptr];
*wptr += 1;
}
if (wrdtyp[*wptr] == 4) {
numdo += 1;
if (numdo > 10)
return (1);
dobjs[numdo - 1] = wrdnum[*wptr];
*wptr += 1;
if (wrdtyp[*wptr] != -2)
return (1);
}
*wptr += 1;
}
}